package utils.encrypt;

import com.sghd.common.utils.json.JsonUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

/**
 * 加密工具类
 * 
 * @author AllenWu
 */
public class EncryptUtil {
	/**
	 * 生成指定位数密钥对
	 * 
	 * @param n
	 *            密钥长度
	 * @return 密钥对(公钥/密钥)
	 * @throws Exception
	 */
	public static Map<String, String> getKeyPair(int n) throws Exception {
		return RSA.generateKeyPair(n);
	}

	/**
	 * 生成1024位数密钥对
	 * 
	 * @return 密钥对(公钥/密钥)
	 * @throws Exception
	 */
	public static Map<String, String> getKeyPair() throws Exception {
		return getKeyPair(0);
	}

	/**
	 * 生成RSA签名
	 * 
	 * @param json
	 *            需要签名的数据
	 * @param privateKey
	 *            密钥
	 * @return 签名密文
	 * @throws UnsupportedEncodingException
	 */
	public static String handleSign(Map<String, Object> json, String privateKey) throws Exception {
		Iterator<Entry<String, Object>> iter = json.entrySet().iterator();
		StringBuffer sbuffer = new StringBuffer();
		String sign = "";
		while (iter.hasNext()) {
			Entry<String, Object> entry = iter.next();
			sbuffer.append(entry.getValue());
		}
		if (StringUtils.isNotEmpty(privateKey)) {
			byte[] data = RSA.sign(sbuffer.toString().getBytes(), Base64.decode2(privateKey));
			sign = new String(Base64.encodeBase64(data));
		}
		return sign;
	}

	/**
	 * RSA加密
	 * 
	 * @param source
	 *            需要加密的数据
	 * @param publicKey
	 *            公钥
	 * @return 密文
	 * @throws Exception
	 */
	public static String encryptRSA(String source, String publicKey) throws Exception {
		byte[] data = RSA.encrypt(source.getBytes(), publicKey.getBytes(), Config.TRANSFORMATION_RSA);
		return new String(Base64.encodeBase64(data));
	}

	/**
	 * AES加密
	 * 
	 * @param source
	 *            需要加密的数据
	 * @param key
	 *            随机加密密钥
	 * @return 密文
	 * @throws UnsupportedEncodingException
	 */
	public static String encryptAES(String source, String key) throws Exception {
		byte[] data = AES.encrypt(source.getBytes(), key.getBytes());
		return new String(Base64.encodeBase64(data));
	}

	/**
	 * 对表单数据进行签名并加密
	 * 
	 * @param data
	 * @return JSONObject
	 * @throws Exception
	 */
	public static Map<String, Object> encryptData(Map<String, Object> data) throws Exception {

		Map<String, Object> params = new HashMap<>();
		// No.1 生成签名 服务器的私钥
		data.put("sign", handleSign(data, Config.PRIVATEKEY));
		// No.2 随机生成16位加密密码
		String merchantAesKey = RandomUtil.getRandom(16);
		// No.3 数据加密
		params.put("encryptData", encryptAES(JsonUtils.object2String(data), merchantAesKey));
		// No.4 加密密码加密 自己的公钥
		params.put("encryptKey", encryptRSA(merchantAesKey, Config.PUBLICKEY));
		params.put("partner", Config.partner);
		return params;
	}
}
